﻿using System;
using System.Text.RegularExpressions;
using System.Web;

using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
#if UMB45
using umbraco.presentation.nodeFactory;
#else
using umbraco.NodeFactory;
#endif

using umbraco.blog4.interfaces;
using System.Collections.Generic;
using System.Linq;
using umbraco.cms.businesslogic;

namespace umbraco.blog4 {
    /// <summary>
    /// The Trackback class.
    /// </summary>
    public class TrackBack {
        private Document _trackback;

        #region .ctor
        public TrackBack(int trackbackId) {
            if (BlogLibrary.IsType(DocumentTypeName, trackbackId))
            {
                _trackback = new Document(trackbackId);

                var postId = BlogLibrary.FindParentId("BlogPost", trackbackId);
                if (postId > -1)
                    Container = new Post(postId);

            } else {
                throw new InvalidOperationException("The given node ID does not point to a valid Trackback.");
            }
        }

        public TrackBack(int postId, string title, string url, string excerpt, string blogName) {
            if (url == String.Empty || url == null || url.Length < 1) throw new NotSupportedException("\"url\" parameter must be specified.");


            if (BlogLibrary.IsType(Post.DocumentTypeName, postId)) { Container = new Post(postId); } else { throw new InvalidOperationException(); }

            // Find the trackback container under the given BlogPost
            Document p = new Document(Container.Id);
            foreach (Document d in p.Children) {
                if (BlogLibrary.TypeAliasInherits(TrackBack.DocumentTypeName, d.ContentType.Alias))
                { 
                    _trackback = Document.MakeNew(title, Blog.DTBlogTrackBack, User.GetUser(0), d.Id);
                    Title = title;
                    Url = url;
                    Excerpt = excerpt;
                    BlogName = blogName;
                    break; 
                }
            }

        }
        #endregion

        #region Properties
        public int ID { get { return _trackback.Id; } }
        public string Title {
            get { return _trackback.Text; }
            set { _trackback.Text = value; _trackback.Save(); }
        }
        public string Url {
            get { return _trackback.getProperty("url").Value.ToString(); }
            set { _trackback.getProperty("url").Value = value; _trackback.Save(); }
        }
        public string Excerpt {
            get { return _trackback.getProperty("bodyText").Value.ToString(); }
            set { _trackback.getProperty("bodyText").Value = value; _trackback.Save(); }
        }
        public string BlogName {
            get { return _trackback.getProperty("blogName").Value.ToString(); }
            set { _trackback.getProperty("blogName").Value = value; _trackback.Save(); }
        }
        public bool IsSpam { get; set; }
        public Post Container { get; private set; }
        #endregion

        public Blog Blog { get { return Container.Blog; } }

        public static string DocumentTypeName { get { return "TrackBack"; } }

        #region Methods
        public void Publish() { _trackback.Publish(User.GetCurrent()); }
        #endregion
    }

    /// <summary>
    /// The TrackBack HttpHandler for intercepting HTTP POST requests from TrackBack-compatible clients.
    /// </summary>
    public class TrackbackPingHandler : IHttpHandler {
        /// <summary>
        /// You will need to configure this handler in the web.config file of your 
        /// web and register it with IIS before being able to use it. For more information
        /// see the following link: http://go.microsoft.com/?linkid=8101007
        /// </summary>
        #region IHttpHandler Members

        public bool IsReusable {
            // Return false in case your Managed Handler cannot be reused for another request.
            // Usually this would be false in case you have some state information preserved per request.
            get { return true; }
        }

        public void ProcessRequest(HttpContext context) {
            string response = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<response>\r\n\t<error>{0}</error>{1}</response>";
            if (context.Request.Url.AbsoluteUri.ToLower().EndsWith(".trkbk")) {
                if (context.Request.HttpMethod != "POST") throw new NotSupportedException("TrackbackPingHandler is designed to only accept POST requests. Please see TrackBack specification at http://www.sixapart.com/pronet/docs/trackback_spec.");
                try {
                    string title = String.IsNullOrEmpty(context.Request.Form["title"]) ? String.Empty : context.Request.Form["title"];
                    if (String.IsNullOrEmpty(context.Request.Form["url"])) throw new NotSupportedException("\"url\" parameter must be specified.");
                    string url = context.Request.Form["url"];
                    string excerpt = String.IsNullOrEmpty(context.Request.Form["excerpt"]) ? String.Empty : context.Request.Form["excerpt"];
                    string blogName = String.IsNullOrEmpty(context.Request.Form["blog_name"]) ? String.Empty : context.Request.Form["blog_name"];

                    context.Response.ClearContent();
                    Regex r = new Regex("[0-9]+");
                    int nodeId = Convert.ToInt32(r.Match(context.Request.Url.AbsoluteUri).Value);
                    if (BlogLibrary.IsType(Post.DocumentTypeName, nodeId))
                    {
                        Post p = new Post(nodeId);
                        TrackBack trackback = new TrackBack(p.Id, title, url, excerpt, blogName);
                        context.Response.Write(String.Format(response, "0", ""));
                    } else {
                        throw new InvalidOperationException();
                    }
                } catch (Exception ex) {
                    Log.Add(LogTypes.Error, -1, String.Format("Unable to create TrackBack for node:{0}",context.Request.QueryString["bp"]));
                    context.Response.Write(String.Format(response, "1",
                        String.Concat("<message>",ex.GetBaseException().Message,"</message>")));
                }
            }
        }
        #endregion
    }
}
